/*
 * Project: book
 * 
 * File Created at 2017年9月12日
 * 
 * Copyright 2016 CMCC Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ZYHY Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license.
 */
package com.whb.book.common.sensitive;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

import com.whb.book.common.redis.RedisUtil;

/**
 * @Type SensitiveWordInit.java
 * @Desc 
 * @author wanghb
 * @date 2017年9月12日 下午12:34:22
 * @version 
 */
@SuppressWarnings("resource")
@Component
public class SensitiveWordInit {

    private static final String ENCODING = "GBK"; //字符编码
    static RedisUtil redisUtil = null;

    @SuppressWarnings("rawtypes")
    public HashMap sensitiveWordMap;

    public SensitiveWordInit() {
        super();
    }

    private static String SPILIT = "#";
    private static int EXPIRE_TIME = 3600;// seconds
    private static String SENSITIVE_WORD = SensitiveWordInit.class.getName();

    private String sensitiveWordKey(String type) {
        StringBuilder sb = new StringBuilder();
        sb.append(type).append(SPILIT).append("sensitiveWordInit");
        return sb.toString();
    }
    
    static{
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                new String[] { "spring/spring-redis.xml","spring/spring-dao.xml"});
        redisUtil = (RedisUtil) ac.getBean("redisUtil");
    }

    /**
     * 
     * @return
     * @throws Exception
     * @since 1.8
     * @author whb
     */
    @SuppressWarnings({ "rawtypes" })
    public Map initKeyWord() {
        try {
            String key = sensitiveWordKey(SENSITIVE_WORD);
            sensitiveWordMap = (HashMap) redisUtil.get(key);
            if (sensitiveWordMap == null) {
                Set<String> set = readSensitiveWordFile();
                addSensitiveWordToHashMap(set);
                redisUtil.set(key, sensitiveWordMap, EXPIRE_TIME);
            }
            return sensitiveWordMap;
        } catch (Exception e) {
            throw new RuntimeException("初始化敏感词库错误",e);
        }
    }

    /**
     * 读取敏感词库，并把内容放到set里
     * @return
     * @throws Exception
     * @since 1.8
     * @author whb
     */
    private Set<String> readSensitiveWordFile() throws Exception {
        Set<String> set = null;
        File file = new File("e:\\sensitiveword.txt");
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
                new FileInputStream(file), ENCODING))) {
            if (file.isFile() && file.exists()) {
                set = new HashSet<String>();
                String txt = null;
                while ((txt = bufferedReader.readLine()) != null) {
                    set.add(txt);
                }
            } else {
                throw new Exception("敏感词库文件不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        return set;

    }

    /**
     * 读取敏感词库，将敏感词放入HashSet中，构建一个DFA算法模型：<br>
     * 中 = {
     *      isEnd = 0
     *      国 = {<br>
     *           isEnd = 1
     *           人 = {isEnd = 0
     *                民 = {isEnd = 1}
     *                }
     *           男  = {
     *                  isEnd = 0
     *                   人 = {
     *                        isEnd = 1
     *                       }
     *               }
     *           }
     *      }
     *  五 = {
     *      isEnd = 0
     *      星 = {
     *          isEnd = 0
     *          红 = {
     *              isEnd = 0
     *              旗 = {
     *                   isEnd = 1
     *                  }
     *              }
     *          }
     *      }
     * @param keyWordSet
     * @since 1.8
     * @author whb
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void addSensitiveWordToHashMap(Set<String> keyWordSet) {
        sensitiveWordMap = new HashMap(keyWordSet.size()); //初始化敏感词容器，避免扩容操作
        String key = null;
        Map nowMap = null;
        Map<String, String> newWorMap = null;
        Iterator<String> iterator = keyWordSet.iterator();
        while (iterator.hasNext()) {
            key = iterator.next();
            nowMap = sensitiveWordMap;
            for (int i = 0; i < key.length(); i++) {
                char charKey = key.charAt(i); //转换成char型
                Object wordMap = nowMap.get(charKey);
                if (wordMap != null) {
                    nowMap = (Map) wordMap; //一个一个放进Map中
                } else { //不存在，则构建一个Map,同时将isEnd设置为0，因为它不是最后一个
                    newWorMap = new HashMap<String, String>();
                    newWorMap.put("isEnd", "0");//不是最后一个
                    nowMap.put(charKey, newWorMap);//没有这个key，就把(isEnd，0) 放在Map中
                    nowMap = newWorMap;
                }
                if (i == key.length() - 1) { //最后一个
                    nowMap.put("isEnd", "1");
                }
            }
        }
    }


}


/**
 * Revision history
 * -------------------------------------------------------------------------
 * 
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2017年9月12日 wanghb create
 */